package org.celery.modules.purchase.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import org.celery.modules.purchase.entity.Purchase;
import org.celery.modules.purchase.vo.PurchaseVO;
import org.celery.modules.purchase.mapper.PurchaseMapper;
import org.celery.modules.purchase.service.IPurchaseService;
import org.celery.modules.shop.entity.Shop;
import org.celery.modules.shop.service.IShopService;
import org.celery.modules.shopStatics.entity.ShopStaticsDay;
import org.celery.modules.ticket.entity.Ticket;
import org.celery.modules.ticket.service.ITicketService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 店铺表 服务实现类
 *
 * @author Celery
 * @since 2023-07-16
 */
@Service
@AllArgsConstructor
public class PurchaseServiceImpl extends BaseServiceImpl<PurchaseMapper, Purchase> implements IPurchaseService {
	private ITicketService ticketService;
	private IShopService shopService;

	@Override
	public IPage<PurchaseVO> selectPurchasePage(IPage<PurchaseVO> page, PurchaseVO purchase) {
		return page.setRecords(baseMapper.selectPurchasePage(page, purchase));
	}

	@Override
	public Boolean savePurchaseObject(Purchase purchase) {
		if(purchase.getStatus() == 2) {
			// 如果是同一家店铺，只参与修改，不增加，避免同一店铺的反复增加
			List<Purchase> listList = list((Wrappers.<Purchase>lambdaQuery().eq(Purchase::getTicketId, purchase.getTicketId())).eq(Purchase::getMailName, purchase.getMailName()).eq(Purchase::getIsDeleted, 0));
			if(listList.size() == 0) {
				if(Func.isNotEmpty(purchase.getPurchaseCode())) {
					// 查询是否存在订单单号purchase_code处于空或者同种的情况，有就不会选择更新，没有才做处理(避免浏览器回退导致的多次存储)
					List<Purchase> list = list((Wrappers.<Purchase>lambdaQuery().eq(Purchase::getPurchaseCode, purchase.getPurchaseCode())).eq(Purchase::getIsDeleted, 0));
					if(list.size() == 0) {
						// 1. 先删除同种订单，根据唯一的数据存储
						if(Func.isNotEmpty(purchase.getTicketId())) {
							update(Wrappers.<Purchase>lambdaUpdate().set(Purchase::getIsDeleted, 1).eq(Purchase::getTicketId,purchase.getTicketId()));
						}
						// 设置订单状态为待付款状态
						Ticket ticket = ticketService.getOne(Wrappers.<Ticket>lambdaQuery().eq(Ticket::getId, purchase.getTicketId()));
						if(Func.isNotEmpty(ticket)) {
							ticket.setPayStatus("未付款");
							ticketService.updateById(ticket);
						}
						// 参与存储
						return save(purchase);
					}
				}
			} else if(listList.size() > 0){
				if(Func.isNotEmpty(purchase.getPurchaseCode())) {
					// 查询是否存在订单单号purchase_code处于空或者同种的情况，有就不会选择更新，没有才做处理(避免浏览器回退导致的多次存储)
					List<Purchase> list = list((Wrappers.<Purchase>lambdaQuery().eq(Purchase::getPurchaseCode, purchase.getPurchaseCode())).eq(Purchase::getIsDeleted, 0));
					if (list.size() == 0) {
						// 设置订单状态为待付款状态
						Ticket ticket = ticketService.getOne(Wrappers.<Ticket>lambdaQuery().eq(Ticket::getId, purchase.getTicketId()));
						if(Func.isNotEmpty(ticket)) {
							ticket.setPayStatus("未付款");
							ticketService.updateById(ticket);
						}
						// 更新存储
						purchase.setId(listList.get(0).getId());
						return updateById(purchase);
					}
				}
			}
		} else if(purchase.getStatus() == 3) {
			// 支付成功，更改状态
			Ticket ticket = ticketService.getOne(Wrappers.<Ticket>lambdaQuery().eq(Ticket::getId, purchase.getTicketId()));
			if(Func.isNotEmpty(ticket)) {
				ticket.setPayStatus("待发货");
				// 待发货的状态
				ticket.setStepStatus("waitsellersend");
				ticketService.updateById(ticket);
			}
			return true;
		}
		return false;
	}

	@Override
	public Boolean getMailName(String mailName) {
		return true;
	}

    @Override
    public Boolean changeTickStatus(String mailName, Integer status) {
		List<Purchase> list = list(Wrappers.<Purchase>lambdaQuery().eq(Purchase::getMailName, mailName).eq(Purchase::getIsDeleted, 0));
		if(list.size() == 1) {
			// 说明需要操作
			Purchase purchase = list.get(0);
			purchase.setStatus(status);
			updateById(purchase);
			// 更新后需要对订单表更改状态
			List<Ticket> list1 = ticketService.list(Wrappers.<Ticket>lambdaQuery().eq(Ticket::getId, purchase.getTicketId()).eq(Ticket::getIsDeleted, 0));
			if(list1.size() == 1) {
				// 这里需要考虑是否需要留下
				Ticket ticket = list1.get(0);
				ticket.setPayStatus("交易关闭");
				ticketService.updateById(ticket);
			}
		}
		return null;
    }

    @Override
    public String getPurchaseLocationGoodList() {
		List<Purchase> list = list(Wrappers.<Purchase>lambdaQuery().eq(Purchase::getIsDeleted, 0));
		if(Func.isNotEmpty(list)) {
			return list.get(0).getPurchaseCode();
		}
		return null;
    }

	@Override
	public List<Map<String, Object>> staticsList(String shopName, LocalDateTime startTime, LocalDateTime endTime, BladeUser user) {
		QueryWrapper<Shop> queryWrapper = new QueryWrapper<>();

		if (Func.isNotEmpty(shopName)) {
			queryWrapper.lambda().like(Shop::getResourceOwner, shopName);
		}

		if(!user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) || (!user.getRoleName().contains("administrator") && !user.getRoleName().contains("s_admin") && !user.getRoleName().contains("caiwu") && !user.getRoleName().contains("fake_boss"))) {
			List<Shop> shopList = shopService.authList(user);
			if (Func.isEmpty(shopList)) {
				return new ArrayList<>();
			}

			List<String> shopNameList = shopList.stream().map(Shop::getResourceOwner).collect(Collectors.toList());
			queryWrapper.lambda().in(Shop::getResourceOwner, shopNameList);
		}

		List<Shop> shopList = shopService.list(queryWrapper);

		QueryWrapper<Ticket> queryWrapperTicket = new QueryWrapper<>();
		if (Func.isNotEmpty(startTime)) {
			queryWrapperTicket.lambda().between(Ticket::getCreateTime, startTime, endTime);
		}
		List<Ticket> ticketList = ticketService.list(queryWrapperTicket);

		List<Long> ticketIds = ticketList.stream().map(Ticket::getId).collect(Collectors.toList());
		List<Purchase> purchaseList;
		if (Func.isNotEmpty(ticketIds)) {
			purchaseList = list(Wrappers.<Purchase>lambdaQuery().in(Purchase::getTicketId, ticketIds));
		} else {
			purchaseList = list();
		}

		List<Map<String, Object>> dataList = new ArrayList<>();
		for (Shop shop: shopList) {
			Map<String, Object> data = new HashMap<>();
			BigDecimal totalTicketAmount = new BigDecimal(0);
			BigDecimal totalBuyAmount = new BigDecimal(0);

			for (Ticket ticket: ticketList) {
				if (ticket.getUserName().equals(shop.getResourceOwner())) {
					totalTicketAmount = totalTicketAmount.add(ticket.getActualPrice());
				}
			}

			for (Purchase purchase: purchaseList) {
				if (Func.isNotEmpty(purchase.getUserName()) && purchase.getUserName().equals(shop.getResourceOwner())) {
					totalBuyAmount = totalBuyAmount.add(purchase.getAmount());
				}
			}
			BigDecimal totalProfitAmount = totalTicketAmount.subtract(totalBuyAmount);

			data.put("shopId", shop.getId().toString());
			data.put("shopName", shop.getResourceOwner());
			data.put("totalTicketAmount", totalTicketAmount);
			data.put("totalBuyAmount", totalBuyAmount);
			data.put("totalProfitAmount", totalProfitAmount);
			if (totalTicketAmount.equals(new BigDecimal(0))) {
				data.put("totalProfitRate", "0%");
			} else {
				data.put("totalProfitRate", totalProfitAmount.divide(totalTicketAmount, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)) + "%");
			}
			dataList.add(data);
		}
		return dataList;
	}

}
